package nl.windgazer.arachne.components.yql;

import nl.windgazer.arachne.services.yql.YQLConduit;
import nl.windgazer.arachne.services.yql.YQLConduitImp;
import nl.windgazer.arachne.services.yql.YQLIPLocation;
import nl.windgazer.arachne.services.yql.YQLLocation;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONObject;


/**
 * 
 * http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20ip.location%20where%20ip%3D'194.145.200.215'&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=
 *
 * env=store://datatables.org/alltableswithkeys
 * 
 * {
 "query": {
  "count": "1",
  "created": "2010-08-31T01:41:40Z",
  "lang": "en-US",
  "results": {
   "Response": {
    "Ip": "194.145.200.215",
    "Status": "OK",
    "CountryCode": "NL",
    "CountryName": "Netherlands",
    "RegionCode": "11",
    "RegionName": "Zuid-Holland",
    "City": "Dordrecht",
    "ZipPostalCode": null,
    "Latitude": "51.8",
    "Longitude": "4.6667",
    "Timezone": "0",
    "Gmtoffset": "0",
    "Dstoffset": "0"
   }
  }
 }
}

 *
 * API for ip.location has changed to something anoying, however, another takes its' place with supposedly more accurate results too:
 * http://query.yahooapis.com/v1/public/yql?q=SELECT%20ip%2C%20latitude%2C%20longitude%20FROM%20pidgets.geoip%20WHERE%20ip%3D'82.95.157.143'&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys
 * @author mreuring
 *
 */
public class YQLIPLocationMap {

	//Injects and Persists

	@Inject
	private YQLConduit yc;
	
	//Properties and Parameters

	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.PROP, name = "width")
	private int _width = 250;

	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.PROP, name = "height")
	private int _height = 250;

	@Parameter(required = true, principal = false, defaultPrefix = BindingConstants.PROP, name = "ip")
	private String _ip;

	private YQLLocation[] locations = null;

	//Components

	//Events

	//Other (check for business-logic, it should not remain here)

	public YQLLocation[] getLocations(String locationString) {
		final StringBuilder ips = new StringBuilder();
		for (final String ip:locationString.split(",")) {
			if (ips.length() > 0) {
				ips.append(" OR ");
			}
			ips.append("ip='");
			ips.append(ip.trim());
			ips.append('\'');
		}//"select * from pidgets.geoip where ip = '" . $_SERVER['REMOTE_ADDR'] . "' &format=json&env=http://datatables.org/alltables.env&callback=cbfunc";"
		ips.insert(0, "SELECT ip, latitude, longitude FROM pidgets.geoip WHERE ");
		final JSONObject locationq = yc.jsonByQuery( ips.toString(), "env", "store://datatables.org/alltableswithkeys");
		System.out.println(ips.toString());
		final int count = locationq.getInt("count");
		if (count==0) {
			return null;
		}

		try {
			final JSONArray pa = locationq.getJSONObject("results").getJSONArray("Result");
			final YQLLocation[] locations = new YQLLocation[pa.length()];
			for (int i = 0; i < pa.length(); i++) {
				final JSONObject location = pa.getJSONObject(i);
				locations[i] = new YQLIPLocation(location);
			}
			return locations;
		} catch (RuntimeException re) {
			final JSONObject o = locationq.getJSONObject("results").getJSONObject("Result");
			final YQLLocation[] locations = new YQLLocation[1];
			locations[0] = new YQLIPLocation(o);
			return locations;
		}
	}

	public YQLLocation[] getLocations() {
		if (locations==null) {
			locations = getLocations(_ip);
		}
		return locations;
	}

	public String getSingleImgUrl() {
		final StringBuilder sb = getBaseURL();

		// &markers=color:blue|label:82.95.157.143|51.8,4.6667
		for (final YQLLocation o: getLocations()) {
			final StringBuilder sbv = new StringBuilder();
			sbv.append("color:blue|label:");
			sbv.append(o.getName());
			sbv.append('|');
			sbv.append(o.getLatitude());
			sbv.append(',');
			sbv.append(o.getLongitude());

			sb.append('&')
			.append(YQLConduitImp.attributes("markers",sbv.toString()));
		}

		return sb.toString();
	}

	public StringBuilder getBaseURL() {
		final StringBuilder sb = new StringBuilder("http://maps.google.com/maps/api/staticmap?zoom=")
		.append('&')
		.append(YQLConduitImp.attributes("size", _width +"x"+ _height))
		.append('&')
		.append(YQLConduitImp.attributes("sensor", false));
		return sb;
	}

	public String getIp() {
		return _ip;
	}

	public void setIp(String ip) {
		_ip = ip;
	}

}
